#pragma once
#include "InfoM.h"
#include "VectorCache.h"
#include "conductivelayer.h"
#include "ZtaskHelper.h"

class LineAbDipole
{
	double	*MsArray;
	int		MsCount;

	ZTaskHelper Zhelper;
	XTaskHelper Vhelper;

	int		TimesCount;
	double	*TimesArray;

	double		**X;
	double		**V;
	double		**DvDz;
	double		**DxDt;
	double		**DxDz;
	VectorCache EzCache;
	VectorCache EyCache;

	ConductiveLayer *Layers;
	int				NumLayers;
	static const InfoM  InfosM[194];
	bool			NeedRecalc;
	double			Length;
	int				SegmentsNum;

private:

	inline double J0Int(double iF1, double iF2, double iR, double iX0, double iX1);
	inline double J1Int(double iF1, double iF2, double iR, double iX0, double iX1);
	
	inline double ExIntFunction(int iMsIndex, int iTimeIndex, double iR, double iX, double iY, double iSigma);
	inline double EyIntFunction(int iMsIndex, int iTimeIndex, double iR, double iX, double iY);	
	inline double EzIntFunction(int iMsIndex, int iTimeIndex, double iR, double iX);
	inline double DBzDtIntFunction(int iMsIndex, int iTimeIndex, double iR, double iX, double iY);
	inline double ByIntFunction(int iMsIndex, double iSigma, int iTimeIndex, double iR, double iX, double iY);

	bool CreateX(double iZ);
	void TimeInterpolation(vector<double> &iFrom, double *oTo, double *iTimes, int iTimeCnt);

	int GetSegmentsNum(double iX, double iY);

public:
	LineAbDipole();

	void SetMedium(ConductiveLayer *iLayers, int iNumLayers);
	void SetLength(double iL) { Length = iL; }
	bool Ex(double iX, double iY, double iZ, double *oResV, double *iTimes, int iTimeCount);
	bool Ey(double iX, double iY, double iZ, double *oResV, double *iTimes, int iTimeCount);
	bool Ez(double iX, double iY, double iZ, double *oResV, double *iTimes, int iTimeCount);
	bool DBzDt(double iX, double iY, double iZ, double *oResV, double *iTimes, int iTimeCount);
	bool By(double iX, double iY, double iZ, double *oResV, double *iTimes, int iTimeCount);

	~LineAbDipole();
};
